home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqdisplay / draw-opti.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-11  |  6.6 KB  |  234 lines

  1. #if defined(NOASM) || \
  2.     defined(USE_ZBUFFER) || \
  3.     !( \
  4.        ((defined(__mc68020__) || defined(__mc68030__)) && defined(__HAVE_68881__)) || \
  5.         defined(__mc68040__) || \
  6.         defined(__mc68060__) \
  7.      )
  8. # undef     NOASM
  9. # define NOASM
  10. # undef  staticvar
  11. # define staticvar
  12. #endif
  13.  
  14. /* clipping */
  15. static point_3d defaultPoints[32], *defaultVList[32];
  16. staticvar fix scan[768][2];
  17.  
  18. void setup_default_point_list(void)
  19. {
  20.   int i;
  21.  
  22.   for (i = 32 - 1; i >= 0; --i)
  23.     defaultVList[i] = &defaultPoints[i];
  24. }
  25.  
  26. /* calculation */
  27. static short int compute_mip_level(__memBase, int face)
  28. {
  29.   /*
  30.    * dumb algorithm: grab 3d coordinate of some vertex,
  31.    * compute dist from viewer
  32.    */
  33.   double dist;
  34.   int se = bspMem->shared.quake1.dfaces[face].firstedge;
  35.   int e = bspMem->shared.quake1.dsurfedges[se];
  36.  
  37.   if (e < 0)
  38.     e = -e;
  39.   dist = scalw(dist2_from_viewer((vec_t *) & bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[e].v[0]].point), -16);    /* / 65536; */
  40.   if (dist < 1)
  41.     return 0;
  42.   if (dist < 4)
  43.     return 1;
  44.   if (dist < 16)
  45.     return 2;
  46.   return 3;
  47. }
  48.  
  49. staticvar float tmap[9];
  50.  
  51. static void compute_texture_gradients(__memBase, struct texture *Text, short int mip)
  52. {
  53.   float uu, vv;
  54.   float tmp0, tmp1, tmp2;
  55.   vec3_t P, M, N;
  56.  
  57.   /* project vectors onto face's plane, and transform */
  58.   transform_vector(M, Text->textGradient.uv0);
  59.   transform_vector(N, Text->textGradient.uv1);
  60.   transform_point_raw(P, Text->textGradient.scaled);
  61.  
  62.   uu = Text->textGradient.u;
  63.   vv = Text->textGradient.v;
  64.  
  65.   /*
  66.    * we could just subtract (u,v) every time we compute a new (u,v);
  67.    * instead we fold it into P:
  68.    */
  69.   P[0] += uu * M[0] + vv * N[0];
  70.   P[1] += uu * M[1] + vv * N[1];
  71.   P[2] += uu * M[2] + vv * N[2];
  72.  
  73.   /*
  74.    * offset by Center of screen--if this were folded into
  75.    * transform translation we could avoid it
  76.    */
  77.   tmp2 = N[0] * M[2] - N[2] * M[0];
  78.   tmp1 = N[1] * M[2] - N[2] * M[1];
  79.   tmp0 = N[0] * M[1] - N[1] * M[0];
  80.   tmp0 -= tmp1 * xCenter + tmp2 * yCenter;
  81.   tmap[8] = tmp2;
  82.   tmap[7] = tmp1;
  83.   tmap[6] = tmp0;
  84.  
  85.   tmp2 = P[2] * M[0] - P[0] * M[2];
  86.   tmp1 = P[2] * M[1] - P[1] * M[2];
  87.   tmp0 = P[1] * M[0] - P[0] * M[1];
  88.   tmp0 -= tmp1 * xCenter + tmp2 * yCenter;
  89.   tmap[5] = scalw(tmp2, -mip);
  90.   tmap[4] = scalw(tmp1, -mip);
  91.   tmap[3] = scalw(tmp0, -mip);
  92.  
  93.   tmp2 = P[0] * N[2] - P[2] * N[0];
  94.   tmp1 = P[1] * N[2] - P[2] * N[1];
  95.   tmp0 = P[0] * N[1] - P[1] * N[0];
  96.   tmp0 -= tmp1 * xCenter + tmp2 * yCenter;
  97.   tmap[2] = scalw(tmp2, -mip);
  98.   tmap[1] = scalw(tmp1, -mip);
  99.   tmap[0] = scalw(tmp0, -mip);
  100. }
  101.  
  102. /*
  103.  * NOTE: subdivision of 16 is a really hard thig, it works most, but you can see sometimes curved textures
  104.  *       if you have some processorpower use 8 instead!
  105.  */
  106. #define SUBDIV_SHIFT    4
  107. #define SUBDIV        (1 << SUBDIV_SHIFT)
  108. #define    SUBDIV_MASK    (SUBDIV - 1)
  109.  
  110. /* draw an affine (linear) span starting at dest, n pixels long, */
  111. /* starting at (u,v) in the texture and stepping by (du,dv) each pixel */
  112. /*
  113.  * if we are in liquid, we can calculate the average pixelcolor
  114.  * of the liquid texture (eg. *lava1) and do a transp with this color
  115.  * so we don't need to change the palette, and the accuracity
  116.  * is better
  117.  *
  118.  * we can make the liquid with a falloff if we use the zbuffer,
  119.  * we have the current z-value, and the z-value at that position
  120.  * we sub them and calculate the transparency-level from that
  121.  * (better use every 10th or like that transparency-level: first,
  122.  *  the transparency is not so accurate, that every percent makes
  123.  *  a change, second, all 100% transparency uses 6,5MB cached
  124.  *  tables, both in memory and on disk (horror!))
  125.  * the falloff is calculated from the brightness of the liquid texture
  126.  * and the type, so brighter texture are more transparent than darker
  127.  *
  128.  * the liquid looks more real if the textures after it also warps
  129.  * so we must determine, which textures lies in liquid, probably
  130.  * we can use the same procedure as the liquid itself, maybe
  131.  * we must project the liquids behaviour to the texture (uff)
  132.  *
  133.  * how to determine if a texture lies in liquid? as I know qbsp
  134.  * splits the plaes at every intersection of two polygons, that
  135.  * means we do not need to split the polygon at the liquid-line
  136.  * the disadvatage of the mark-texture-in-liquid is, that while
  137.  * we are in liquid, the textures outside the liquid doesn't warp
  138.  *
  139.  * probably we can do real wave in liquid, for that we do not change
  140.  * the du or dv, but the z-value (upwards) of the polygon in a
  141.  * reproducable caustics manner, the difficulty is, to calculate this
  142.  * values in the very inner loop (draw_affine), thats slow
  143.  *
  144.  * how to avoid this mipmap shiftig and masking in liquid textures:
  145.  * after building the waterblock convert the scanlines from this:
  146.  *
  147.  * +----+ example: memory-block-size is 64*64
  148.  * |****|          mipmap-size is 32*32
  149.  * |    |          memory is linear
  150.  * |    |
  151.  * |    |
  152.  * +----+
  153.  *
  154.  * interally handled as this:   to this:
  155.  *                              
  156.  * +--+                         +----+ we need no shiftig, on masking
  157.  * |**|                         |**  | and it is faster, 'cause the 
  158.  * |**|                         |**  | conversion could be cached and is
  159.  * +--+                         |    | out of the span-draw-inner-loop
  160.  *                              |    |
  161.  *                              +----+
  162.  *
  163.  * we can even remove all the shifting, if we put the warp-textures
  164.  * in a 256*64 block, so the offset is 0x0000xxyy (0b000000000000000000xxxxxx00yyyyyy)
  165.  * that is a 16k-block per watertexture, not too much
  166.  *
  167.  * probably it could be faster, if we call a hook defined in the TextureCache
  168.  */
  169.  
  170. #ifndef NOASM
  171. #ifdef DRIVER_8BIT
  172. #include "drawSpans8-m68k2.S"
  173. #include "drawSpans8flat-m68k2.S"
  174. #include "drawSpans8wire-m68k2.S"
  175. #endif
  176. #ifdef DRIVER_16BIT
  177. #include "drawSpans16-m68k2.S"
  178. #endif
  179. #ifdef DRIVER_24BIT
  180. #include "drawSpans24-m68k2.S"
  181. #endif
  182. #ifdef DRIVER_32BIT
  183. #include "drawSpans32-m68k2.S"
  184. #endif
  185. #else
  186. #ifdef DRIVER_8BIT
  187. #include "draw-opti8.c"
  188. #include "draw-opti8flat.c"
  189. #include "draw-opti8wire.c"
  190. #endif
  191. #ifdef DRIVER_16BIT
  192. #include "draw-opti16.c"
  193. #endif
  194. #ifdef DRIVER_24BIT
  195. #include "draw-opti24.c"
  196. #endif
  197. #ifdef DRIVER_32BIT
  198. #endif
  199. #endif
  200.  
  201. /* preparing */
  202. static inline void scan_convert(point_3d * a, point_3d * b)
  203. {
  204.   int right;
  205.   fix x, dx;
  206.   int y, ey;
  207.  
  208.   if (a->sy == b->sy)
  209.     return;
  210.  
  211.   if (a->sy < b->sy)
  212.     right = 0;
  213.   else {
  214.     void *temp = a;
  215.  
  216.     a = b;
  217.     b = temp;
  218.     right = 1;
  219.   }
  220.  
  221.   /* compute dxdy */
  222.   dx = FLOAT_TO_INT(scalw((b->sx - a->sx), 16) / (b->sy - a->sy));    /* * 65536.0 */
  223.   x = a->sx;
  224.   y = FIX_INT(a->sy);
  225.   ey = FIX_INT(b->sy);
  226.   x += FLOAT_TO_INT(((double)dx * ((y << 16) - a->sy)) * (1 / 65534.0));
  227.  
  228.   while (y < ey) {
  229.     scan[y][right] = FIX_INT(x);
  230.     x += dx;
  231.     ++y;
  232.   }
  233. }
  234.